package com.binguo.service;

import com.binguo.common.exception.ServiceException;
import com.binguo.common.util.SHA1;
import com.binguo.entity.TokenVO;
import com.binguo.model.model.Employee;
import com.binguo.model.model.Token;
import com.binguo.model.repository.EmployeeRepository;
import com.binguo.model.repository.TokenRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Condition;

import java.util.Date;
import java.util.UUID;

import static com.binguo.common.exception.ErrorCode.*;


/**
 * Created by haibang on 18/5/7.
 */
@Service
public class TokenService {

    private static Logger logger = LoggerFactory.getLogger(TokenService.class);



    @Autowired
    TokenRepository tokenRepository;

    @Autowired
    EmployeeRepository employeeRepository;


    public TokenVO createToken(String refId, String deviceId){
        try {
        String sessionKey = UUID.randomUUID().toString();
        String content = refId + deviceId + sessionKey;
        String tokenStr = SHA1.SHA1(content);
        Token token = Token.builder()
                .refid(refId)
                .deviceid(deviceId)
                .sessionkey(sessionKey)
                .token(tokenStr).build();
        tokenRepository.save(token);
        return TokenVO.builder().userId(refId).token(tokenStr).expiresIn(7200).build();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(CREATE_TOKEN_ERROR);
        }
    }

    public TokenVO refreshToken(String refId, String deviceId){
        checkDeviceId(refId, deviceId);
        deleteToken(refId, deviceId);
        return createToken(refId, deviceId);
    }


    public Boolean validateToken(String refId, String deviceId, String token){
        Condition condition = new Condition(Token.class);
        condition.or().andEqualTo("refid", refId)
                .andEqualTo("deviceid", deviceId);
       return tokenRepository.findByCondition(condition).stream().findFirst().map(token1 -> {
            if(!token.equals(token1.getToken())) throw new ServiceException(TOKEN_INVALID);
            Date date = new Date(System.currentTimeMillis() - 7200*1000);
            if(token1.getCreated().before(date)) throw new ServiceException(TOKEN_EXPIRE);
            return true;
        }).orElseThrow(() -> new ServiceException(TOKEN_EXPIRE));
    }

    public void deleteToken(String refId, String deviceId){
        Condition condition = new Condition(Token.class);
        condition.or().andEqualTo("refid", refId)
                .andEqualTo("deviceid", deviceId);
        tokenRepository.deleteByCondition(condition);
    }


    private void checkDeviceId(String refId, String deviceId){
        Condition condition = new Condition(Employee.class);
        condition.or().andEqualTo("id", refId)
                .andEqualTo("deviceid", deviceId);
        if(employeeRepository.findByCondition(condition).isEmpty()) throw new ServiceException(DEVICE_ID_NOT_EXIST);
    }



}
